#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64

#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <poll.h>
#include <signal.h>
#include <stdint.h>
#include <errno.h>
#include <stdlib.h>
#include <pthread.h>
#include <byteswap.h>
#include <string.h>
#include <ctype.h>
#include <termios.h>
#include <sys/mman.h>
#include <arpa/inet.h>


#include "log.h"

#define LOG_TAG "make_data.c :"

#define M_B (1024 * 1024UL)
#define BUFF_SIZE  2048
#define FPGA_WORD_LEN  8

typedef long long int data_size_type;

int main(int argc, char **argv)
{
    data_size_type data_size = 50 * M_B;
    long int start_pos = 0, i = 0;
    char *stop_point = NULL;
    int data_fd = -1, ret_val = -1;

    data_size_type *buffer = NULL;

    if (argc < 4)
    {
        LOG("usage:./%s file_name data_size start_pos channel_num\r\n",argv[0]);
        return -1;
    }

    LOG("sizeof(data_size_type) %lu\r\n", sizeof(data_size_type));

    if (argv[2])
        data_size = strtol(argv[2], &stop_point, 0) * M_B;

    if (argv[3])
        start_pos = strtol(argv[3], &stop_point, 0);
    
    if(argv[4]) start_pos |= (strtol(argv[4], &stop_point, 0) << ((sizeof(data_size_type) - 1) * 8)); 

    data_fd = open(argv[1], O_RDWR | O_CREAT | O_LARGEFILE);
    ERR_LOG(LOG_TAG, "open ", data_fd < 0);

    ret_val = ftruncate(data_fd, 0);
    ERR_LOG(LOG_TAG, "ftruncate", ret_val < 0);

    chmod(argv[1], 0766);
    ret_val = lseek(data_fd, 0, SEEK_SET);
    ERR_LOG(LOG_TAG, "lseek", ret_val < 0);

    buffer = (data_size_type *)malloc(BUFF_SIZE);
    if (!buffer)
    {
        LOGE(LOG_TAG"malloc failed,errno = %d\r\n", errno);
        goto err_out;
    }

    while (1)
    {
        memset(buffer, '\0', BUFF_SIZE);
        for (i = 0; i < BUFF_SIZE / sizeof(data_size_type); i += (FPGA_WORD_LEN / sizeof(data_size_type)))
        {
            //buffer[i] = htonl(start_pos);
            buffer[i] = start_pos;
            start_pos++;
        }
        ret_val = write(data_fd, buffer, BUFF_SIZE);
        ERR_LOG(LOG_TAG, "write", ret_val < 0);
        data_size -= BUFF_SIZE;
        if (data_size == 0) break;
    }

err_out:
    if (!buffer) free(buffer);
    if (data_fd >= 0) close(data_fd);
    return 0;
}
